package cn.dev33.satoken;

import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.stp.StpLogic;
import com.csap.framework.extension.CsapException;
import com.csap.framework.util.Assert;
import com.csap.framework.util.StringUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Sa-Token 权限验证工具类
 *
 * @Author ycf
 * @Date 2021/8/17 6:40 下午
 */
@Slf4j
public class LoginUtil {
    /**
     * 账号类型标识
     */
    public static final String TYPE = "login";
    public static final String USER_TYPE = "userType";
    public static final String PLATFORM = "platform";
    public static final String LOGIN_TYPE = "loginType";
    public static final String CLIENT_ID = "clientId";
    public static final String CLIENT_SECRET = "clientSecret";
    private static final Map<String, StpLogic> STRING_STP_LOGIC_MAP = new ConcurrentHashMap<>(16);

    /**
     * 是否存在登录类型
     *
     * @param type 类型
     * @return 结果
     */
    private static Boolean contains(String type) {
        return STRING_STP_LOGIC_MAP.containsKey(type);
    }

    /**
     * 获取实例
     *
     * @param type 账号类型
     * @return 返回操作的util
     */
    public static StpLogic getInstance(String type) {
        return (StringUtil.isEmpty(type) || !STRING_STP_LOGIC_MAP.containsKey(type)) ? getDefaultInstance() : STRING_STP_LOGIC_MAP.get(type);
    }

    /**
     * 获取默认实例
     *
     * @return 返回操作的util
     */
    public static StpLogic getDefaultInstance() {
        return STRING_STP_LOGIC_MAP.get(TYPE);
    }


    /**
     * 获取当前请求的实例
     *
     * @return 返回用户操作类
     */
    public static StpLogic getInstance() {
        return getInstance(loginType());
    }

    /**
     * 获取登录类型 返回登录类型
     *
     * @return 结果
     */
    public static String loginType() {
        SaTokenConfig saTokenConfig = SaManager.getConfig();
        String loginType = saTokenConfig.getLoginType();
        String value = null;
        if (saTokenConfig.getIsReadHead()) {
            value = SaHolder.getRequest().getHeader(loginType);
        }
        if (StringUtil.isEmpty(value) && saTokenConfig.getIsReadCookie()) {
            value = SaHolder.getRequest().getCookieValue(loginType);
        }
        if (StringUtil.isEmpty(value) && saTokenConfig.getIsReadBody()) {
            value = SaHolder.getRequest().getParam(loginType);
        }
        if (StringUtil.isEmpty(value) && saTokenConfig.getLoginTypeMust()) {
            throw new SaTokenException(String.format("登录类型为%s", loginType));
        }
        if (log.isDebugEnabled()) {
            log.debug("getRequestInstance request data loginType is :{}", value);
        }
        return StringUtil.isEmpty(value) ? LoginUtil.TYPE : value;
    }

    /**
     * 获取用户类型
     *
     * @return 用户类型
     */
    public static String userType() {
        String valueType = SaHolder.getRequest().getHeader(USER_TYPE);
        if (StringUtil.isEmpty(valueType)) {
            valueType = SaHolder.getRequest().getParam(USER_TYPE);
        }
        if (StringUtil.isEmpty(valueType) && log.isDebugEnabled()) {
            log.debug("getRequestInstance request data loginType is :{}", valueType);
        }
        return StringUtil.isEmpty(valueType) ? "default" : valueType;
    }

    /**
     * 获取平台标识
     *
     * @return 平台标识
     */
    public static String platform() {
        String value = SaHolder.getRequest().getHeader(PLATFORM);
        if (StringUtil.isEmpty(value)) {
            value = SaHolder.getRequest().getParam(PLATFORM);
        }
        if (StringUtil.isEmpty(value)) {
            throw new CsapException("platform not null");
        }
        return value;
    }

    /**
     * 获取平台标识
     *
     * @return 平台标识
     */
    public static String clientId() {
        String value = SaHolder.getRequest().getHeader(CLIENT_ID);
        if (StringUtil.isEmpty(value)) {
            value = SaHolder.getRequest().getParam(CLIENT_ID);
        }
        if (StringUtil.isEmpty(value)) {
            throw new CsapException("platform not null");
        }
        return value;
    }

    /**
     * 获取平台标识
     *
     * @return 平台标识
     */
    public static String clientSecret() {
        String value = SaHolder.getRequest().getHeader(CLIENT_SECRET);
        if (StringUtil.isEmpty(value)) {
            value = SaHolder.getRequest().getParam(CLIENT_SECRET);
        }
        if (StringUtil.isEmpty(value)) {
            throw new CsapException("platform not null");
        }
        return value;
    }

    /**
     * 初始化
     *
     * @param loginType 登录类型
     */
    public static void init(Map<String, SaTokenConfig> loginType, SaTokenConfig saTokenConfig) {
        loginType.forEach((key, value) -> STRING_STP_LOGIC_MAP.put(key, new StpLogic(key) {
            @Override
            public SaTokenConfig getConfig() {
                return value;
            }
        }));
        if (!STRING_STP_LOGIC_MAP.containsKey(TYPE)) {
            STRING_STP_LOGIC_MAP.put(TYPE, new StpLogic(TYPE) {
                @Override
                public SaTokenConfig getConfig() {
                    return saTokenConfig;
                }
            });
        }
    }

}
